#region Terms of Usage
/*
 * Copyright 2006 Sameera Perera
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using needle.Services.soab.RequestQueue;
using needle.Services.soab.Data;
using System.ComponentModel;
using System.Reflection;

using needle.Services.soab.Connectivity;

using needle.Properties;

using needle.Services.soab.Cache;

namespace needle.Services.soab
{
    public class ServiceAgent
    {
        protected Executor executor;

        /// <summary>Handler for async completed event</summary>
        protected virtual void OnExecuteCompleted<T>( object sender, T e ) where T : AsyncCompletedEventArgs
        {
            if ( e.UserState != null && e.UserState is ServiceRequest)
            {
                ServiceRequest rqst = (ServiceRequest)e.UserState;

                // Find the callback method and execute it
                MethodInfo mi   = this.GetType().GetMethod(
                                        rqst.CallbackMethodName,
                                        new Type[] { typeof( ServiceResponse ) } );
                if ( mi != null )
                {
                    object result   = null;

                    if ( e.Error == null )
                    {
                        PropertyInfo pi   = e.GetType().GetProperty( "Result" );
                        if ( pi != null )
                            result = pi.GetValue( e, null );
                        // Update the status of the request
                        rqst.Status = ServiceRequestStatus.Completed;
                    }
                    else
                        rqst.Status = ServiceRequestStatus.Errored;

                    ServiceResponse response = new ServiceResponse( result, rqst, e );
                    mi.Invoke( this, new object[] { response } );
                }

                // Update the request's status and remove the object from the queue
                QueueManager.Instance.Dequeue( rqst );
            }
        }

        public ServiceAgent()
        {
            this.executor   = new Executor(this);
        }
    }
}
